

<template>
  <view class="Mall4j chat-container" :class="{ chatad: modelType }" :style="{position:(modelType || fixedFlag)?'static':'fixed'}">
    <view class="content">
      <!-- #ifdef H5 -->
      <view class="shop-info" @touchmove.stop.prevent="discard">
        <image class="back-icon" src="https://mall-1312577323.cos.ap-chengdu.myqcloud.com/mall/images/icon/down-arrow.png" mode="" @tap="backToPre" />
        <view class="shop-tit">{{ i18n.mallCustomerService }}
          <text :class="['shop-status', isOnline?'in':'out']">{{ isOnline?i18n.online:i18n.offline }}</text>
        </view>
      </view>
      <!-- #endif -->
      <scroll-view id="input-text" class="msg-list" scroll-y="true" :style="{height: screenHeight+'px'}" :scroll-with-animation="scrollAnimation" :scroll-top="chatScrollTop" @scrolltoupper="changeScollY" @scroll="bindscroll" @touchstart="hideKeyboard" @touchmove="touchMove" @touchend="touchEnd">
        <view v-if="showRefresh" style="width:100%;position:relative;padding:60rpx 0;">
          <view class="text-gray" style="position: absolute;left: 50%;top: 50%;transform: translate(-50%, -50%);">
            <view class="flex">
              <view class="lzy-loading" />
              <!-- <view>刷新中...</view> -->
            </view>
            <!-- <view v-else class="text">
              释放刷新
            </view> -->
          </view>
        </view>
        <view v-for="(row, index) in msgItems" :key="index" class="row" @touchmove="touchMove">
          <!-- 用户消息 -->
          <block>
            <view class="topTime">{{ row.timeStr }}</view>
            <!-- 自己发出的消息 -->
            <view v-if="row.source == 2" class="my">
              <!-- 左-消息 -->
              <view class="left">
                <!-- 文字消息 -->
                <view v-if="row.employeeUnread" key="read" class="unread">{{ i18n.read }}</view>
                <view v-if="!row.employeeUnread" key="unread" class="unread">{{ i18n.unRead }}</view>

                <view v-if="row.type == 0 && !row.prodInfo" class="bubble">
                  <rich-text :nodes="row.content" />
                </view>
                <!-- 图片消息 -->
                <view v-if="row.type == 1 && !row.prodInfo" class="bubble" @tap="showPic(row.content)">
                  <image :src="row.content" class="longimage" mode="widthFix" />
                </view>
                <!-- 商品链接 -->
                <!-- <view class="prod-link" v-if="row.prodInfo" @tap='toProdDetail(row.prodInfo.prodId)'>
									<view class="link-prod prod-no">
										<img :src="row.prodInfo.imgs" alt="">
										<view class="link-detail">
											<view class="prod-name">{{row.prodInfo.prodName}}</view>
											<view class="prod-price">￥{{row.prodInfo.price}}</view>
										</view>
									</view>
								</view> -->
                <view v-if="row.prodInfo" class="prod-link" @tap="toProdDetail(row.prodInfo)">
                  <view v-if="row.prodInfo.orderFlag" class="prod-number">{{ i18n.orderNumber }}：{{ row.prodInfo.orderNumber }}</view>
                  <view class="link-prod prod-no">
                    <img :src="row.prodInfo.imgs" alt="">
                    <view class="link-detail">
                      <view class="prod-name">
                        {{ row.prodInfo.prodName }}
                      </view>
                      <view class="prod-price">
                        <!-- <text v-if="row.prodInfo.orderFlag">{{i18n.paymentAmount+':'}}{{ row.prodInfo.actualTotal?'￥'+row.prodInfo.actualTotal: ' ' }}<text v-if="row.prodInfo.useScore">{{row.prodInfo.actualTotal?'+':''}}{{row.prodInfo.useScore}} {{i18n.points}}</text></text> -->
                        <text>{{ row.prodInfo.price?'￥':'' }}{{ row.prodInfo.price?row.prodInfo.price:'' }}{{ (row.prodInfo.price && row.prodInfo.useScore)?'+':'' }}<text v-if="row.prodInfo.useScore">{{ row.prodInfo.useScore }} {{ i18n.points }}</text></text>
                        <!-- <text v-if="row.prodInfo.orderFlag">
											{{
											[
												'',
												i18n.pendingPayment,
												i18n.pendingDelivery,
												i18n.pendingReceipt,
												i18n.pendinEvaluation,
												i18n.completed,
												i18n.canceled,
												i18n.grouping
											][row.prodInfo.status]
											}}
										</text> -->
                      </view>
                    </view>
                  </view>
                </view>

              </view>
              <!-- 右-头像 -->
              <view class="right">
                <image v-if="!row.userHeadUrl" src="https://mall-1312577323.cos.ap-chengdu.myqcloud.com/mall/images/chat/userImg.jpg" />
                <image v-else :src="row.userHeadUrl" />
              </view>
            </view>
            <!-- 别人发出的消息 -->
            <view v-if="(row.source == 0 || row.source == 1) && row.forwardCode != 1" class="other">
              <!-- 左-头像 -->
              <view class="left">
                <image :src="row.shopLogo ? row.shopLogo: 'https://mall-1312577323.cos.ap-chengdu.myqcloud.com/mall/images/icon/head01.png'" />
              </view>
              <!-- 右-用户名称-时间-消息 -->
              <view class="right">
                <!-- 文字消息 -->
                <view v-if="row.type == 0" class="bubble">
                  <rich-text :nodes="row.content" />
                </view>
                <!-- 图片消息 -->
                <view v-if="row.type == 1" class="bubble" @tap="showPic(row.content)">
                  <image :src="row.content" class="longimage" mode="widthFix" />
                </view>
                <!-- <view class="unread">已读</view>
								<view>未读</view> -->
              </view>
            </view>

            <!-- 发送链接 -->
            <view v-if="row.source == 3" class="link-box">
              <!-- <view class="link-prod" @tap='toProdDetail(row.prodInfo.prodId)'>
								<img :src="row.prodInfo.imgs" alt="">
								<view class="link-detail">
									<view class="prod-name">{{row.prodInfo.prodName}}</view>
									<view class="prod-price">￥{{row.prodInfo.price}}</view>
								</view>
							</view> -->
              <view v-if="row.prodInfo.orderFlag" class="prod-number">{{ i18n.orderNumber }}：{{ row.prodInfo.orderNumber }}</view>
              <view class="link-prod" @tap="toProdDetail(row.prodInfo)">
                <img :src="row.prodInfo.imgs" alt="">
                <view class="link-detail">
                  <view class="prod-name">
                    {{ row.prodInfo.prodName }}
                  </view>
                  <view class="prod-price">
                    <!-- <text v-if="row.prodInfo.orderFlag">{{i18n.paymentAmount+':'}}{{ row.prodInfo.actualTotal?'￥'+row.prodInfo.actualTotal: ' '}}<text v-if="row.prodInfo.useScore">{{row.prodInfo.useScore}} {{i18n.points}}</text></text> -->
                    <text>{{ row.prodInfo.price?'￥':'' }}{{ row.prodInfo.price?row.prodInfo.price:'' }}{{ (row.prodInfo.price && row.prodInfo.useScore)?'+':'' }}<text v-if="row.prodInfo.useScore">{{ row.prodInfo.useScore }} {{ i18n.points }}</text></text>
                    <!-- <text v-if="row.prodInfo.orderFlag">
											{{
											[
												'',
												i18n.pendingPayment,
												i18n.pendingDelivery,
												i18n.pendingReceipt,
												i18n.pendinEvaluation,
												i18n.completed,
												i18n.canceled,
												i18n.grouping
											][row.prodInfo.status]
											}}
                    </text> -->
                  </view>
                </view>
              </view>
              <view class="link-send" @click="sendText(2)">{{ i18n.sendLink }} <i class="link-send-right" /></view>
            </view>

            <!-- 系统提示: 客服接入/转接、客户离线、用户状态异常-->
            <view v-if="(row.source == -1 && row.tipsType) || row.type == 2" class="sys-tips">
              <text v-if="row.type == 2" class="tips-content">{{ row.content }}</text>
              <text v-else class="tips-content">{{ row.tipsType==1?i18n.customerOffline:row.tipsType==2?i18n.loginOtherSide:i18n.reLogin }}</text>
            </view>

          </block>
        </view>
      </scroll-view>
    </view>

    <!-- 底部输入栏 -->
    <view v-if="tabbar" id="input-heigh" class="input-box" :class="popupLayerClass" @touchmove.stop.prevent="discard">
      <view class="textbox">
        <view class="text-mode" @tap="chatFocus">
          <view class="box">
            <input v-model="textMsg" type="text" confirm-type="send" style="width:100%" hold-keyboard="true" @click.stop.native="textareaFocus" @confirm="sendText(1)" @blur="listeningfocus">
          </view>
        </view>
      </view>
      <view class="more" @tap="showMore">
        <image class="icon add" src="https://mall-1312577323.cos.ap-chengdu.myqcloud.com/mall/images/chat/add.png" />
      </view>
      <view class="send" @tap="sendText(1)">
        <view class="btn">{{ i18n.send }}</view>
      </view>
    </view>

    <!-- 抽屉栏 -->
    <view class="popup-layer" :class="popupLayerClass" @touchmove.stop.prevent="discard">
      <!-- 更多功能 相册-拍照-红包 -->
      <view class="more-layer" :class="{ hidden: hideMore }">
        <view class="list">
          <view class="box" @tap="chooseImage">
            <view class="icon tupian2" />
          </view>
          <view class="box" @tap="camera">
            <view class="icon paizhao" />
          </view>
        </view>
      </view>
    </view>

    <!-- 未读消息提醒-->
    <view v-if="totalUserUnread>0" class="un-read-tips">
      <image src="https://mall-1312577323.cos.ap-chengdu.myqcloud.com/mall/images/icon/unread-up.png" class="un-read-icon" />
      {{ `${totalUserUnread}${i18n.unread}` }}
    </view>

  </view>
</template>
<script module="wxs" lang="wxs" src="../../wxs/number.wxs"></script>

<script>
import {
  mapState,
  mapMutations
} from 'vuex';
import http from "../../utils/http.js";
import config from "../../utils/config.js";
import util from "../../utils/util.js";
import { Base64 } from '../../js_sdk/base64/base64'
import { localAgree } from '@/utils/localagree'
export default {
  data () {
    return {
      prodInfo: null, //商品链接
      shopId: null,
      //文字消息
      textMsg: '',
      scrollAnimation: false,
      myuid: 0,
      current: 1, //聊天记录页数
      pages: 1, //聊天记录页码数
      isOnline: false,//判断有无在线
      pages: '',
      // 抽屉参数
      popupLayerClass: '',
      // more参数
      hideMore: true,
      user: uni.getStorageSync('user'),
      msgItems: [],
      imSocketTask: null,
      userInfo: null,
      shopInfo: null,
      chatScrollTop: 0,
      screenHeight: 712, // 消息内容盒子默认高度
      actualHeight: 712, // 手机屏幕实际高度
      sendType: 2, // 发送消息类型(客服类型)  1平台  2商家  默认平台
      lastTime: '',
      times: 0,  // 次数 显示
      totalUserUnread: 0,// 有多少条未读新消息
      messageInfo: {}, // 商家发送的文本消息
      userSend: false, //是否是用户发送的消息判断
      userRead: true,  // 用户的已读未读判断
      lockReconnect: false,
      tabbar: true,
      windowHeight: '',
      modelType: null,
      softKeyboards: false,
      oldScreenHeight: null,
      fixedFlag: null,

      screenOnce: 0,
      modelType: null,
      openBox: false,
      triggered: true, //自定义下拉刷新
      _freshing: false, //是否处在刷新状态下
      freshStatus: 'more', // 当前刷新的状态
      showRefresh: false,   // 是否显示下拉刷新组件
      scollTopTag: '',
      startY: ''
    };
  },
  computed: {
    i18n () {
      return this.$t('index')
    }
  },
  onLoad (option) {

    this.getSysInfo()
    this.getUserInfo();
    this.prodId = option.prodid
    this.shopId = 1

    uni.setNavigationBarTitle({
      title: uni.getStorageSync('appType') != 4 ? this.i18n.mallCustomerService + ` ${this.isOnline ? this.i18n.online : this.i18n.offline}` : this.i18n.mallCustomerService
    })
    this.noServiceDialog()
  },
  onUnload: function () {
    this.closeWs();
  },
  // 下拉加载刷新页面
  // onPullDownRefresh() {
  // 	this.current +=1;
  // 	if (this.loginOtherSide) {
  // 	    wx.stopPullDownRefresh()
  // 		wx.showToast({
  // 			title: this.i18n.loginOtherSide,
  // 			icon: 'none',
  // 		})
  // 	}else if(this.current<=this.pages){
  // 		this.getMsgItems()
  // 	}else{
  // 		wx.stopPullDownRefresh()
  // 		wx.showToast({
  // 			title: this.i18n.allLoaded,
  // 			icon: 'none',
  // 		})
  // 	}
  // },
  methods: {
    // 兼容小程序
    ...mapState(['baseUrl']),
    changeScollY () {
      this.scollTopTag = 0
    },
    /**
     * 获取屏幕高度
     */
    getSysInfo () {
      uni.getSystemInfo({
        success: (sysInfo) => {
          // #ifdef H5
          // this.screenHeight = sysInfo.windowHeight - 55
          // this.actualHeight = sysInfo.windowHeight - 55
          if (sysInfo.platform === 'ios') {
            this.modelType = true
          }
          if (this.softKeyboards) {
            // let kebodyHeight = screen.height - window.innerHeight
            this.screenHeight = this.oldScreenHeight
          } else {
            this.screenHeight = sysInfo.windowHeight - 55
            this.actualHeight = sysInfo.windowHeight - 55
            if (!this.screenOnce) {
              this.oldScreenHeight = this.screenHeight
            }
          }
          // #endif
          // #ifdef MP-WEIXIN
          this.screenHeight = sysInfo.screenHeight - 105 - sysInfo.statusBarHeight
          this.actualHeight = sysInfo.screenHeight - 105 - sysInfo.statusBarHeight
          this.oldScreenHeight = this.screenHeight
          uni.showToast({
            title: this.oldScreenHeight
          })
          // #endif
          // #ifdef APP-PLUS
          this.screenHeight = sysInfo.windowHeight - 50
          this.actualHeight = sysInfo.windowHeight - 50

          this.oldScreenHeight = this.screenHeight
          // #endif
        }
      })
    },
    /**
     * 点击外面盒子获取焦点
     */
    chatFocus () {
      this.textareaFocus()
    },

    /**
     * 打电话给商家
     */
    callShop () {
      uni.makePhoneCall({
        phoneNumber: this.shopInfo.tel
      })
    },
    /**
     * 返回上一页
     */
    backToPre () {
      if (this.prodId) {
        this.$Router.replace({ path: '/pages/prod/prod', query: { prodid: this.prodId } })
      } else {
        if (this.shopId == 0) {
          uni.navigateBack({
            delta: 1
          })
        } else {
          uni.navigateBack({
            url: '/pages/chat/chat'
          })
        }
      }
    },

    //判断是否为JSON格式
    isJSON (str) {
      if (typeof str == 'string') {
        try {
          JSON.parse(str);
          return true;
        } catch (e) {
          return false;
        }
      }
    },

    /**
     * 获取聊天记录
     */
    getMsgItems () {
      let messageInfo = {
        history: 1,
        current: this.current,
        size: 10,
        sendType: this.sendType,
        toId: this.shopId
      }
      this.imSocketTask.send({
        data: JSON.stringify(messageInfo)
      })
    },

    // 获取当前商家在线离线状态
    getOnlineStatus () {
      let status = {
        onlineOrOffline: true,
        sendType: this.sendType,
        toId: this.shopId
      }
      try {
        this.imSocketTask.send({ data: JSON.stringify(status) })
      } catch (error) {
        this.$message({
          message: '连接已断开请刷新一下页面',
          type: 'error',
          duration: 1000
        })
      }
    },

    /**
     * 获取用户信息
     */
    getUserInfo () {
      var params = {
        url: "/p/user/userInfo",
        method: "GET",
        data: {},
        dontTrunLogin: true,
        callBack: (res) => {
          this.userInfo = res
          this.openWs();
        }
      };
      http.request(params);
    },

    /**
     * 获取商品或订单信息并生成相应的链接
     */
    getProdInfo (id, type) {
      // type 1 = 商品链接  type 2 = 订单链接
      let data = type == 1 ? { prodId: id } : { orderNumber: id }
      let prodInfo = null
      var params = {
        url: type == 1 ? "/prod/prodInfo" : "/p/myOrder/orderDetail",
        method: "GET",
        data,
        callBack: res => {
          if (type == 1) {
            prodInfo = {
              imgs: res.pic,
              prodId: res.prodId,
              prodName: res.prodName,
              skuName: res.skuName,
              price: res.price,
              prodId: res.prodId,
              orderType: res.orderType,
              actualTotal: res.price
            }
          } else {
            let orderItem = res.orderItemDtos[0]
            prodInfo = {
              imgs: orderItem.pic,
              prodId: orderItem.prodId,
              orderNumber: this.$Route.query.orderNumber,
              skuName: orderItem.skuName,
              prodName: orderItem.prodName,
              price: res.actualTotal,
              prodId: orderItem.prodId,
              actualTotal: res.actualTotal,
              useScore: res.orderScore,
              status: res.status,
              orderType: res.orderType,
              orderFlag: true // 订单判断
            }
          }
          this.setData({
            prodInfo
          })

          let msgItem = {
            source: 3, //表示产品链接
            timestamp: new Date().getTime(),
            toId: this.shopId,
            prodInfo,  //产品链接详情
            msgType: 0,
            sendType: this.sendType // 1发给平台   2发给商家
          }

          msgItem.timeStr = util.tsToDate(new Date().getTime(), 'M月D日 h:m')
          // if(!this.msgItems.length){

          // 	msgItem.timeStr = util.tsToDate(new Date().getTime(), 'M月D日 h:m')

          // }else{

          // 	let prevTime = util.tsToDate(this.msgItems[this.msgItems.length-1].timestamp,'M月D日 h:m')

          // 	let nowTime = util.tsToDate(new Date().getTime(), 'M月D日 h:m')
          // 	if(prevTime.slice(0,prevTime.indexOf(' ')) == nowTime.slice(0,nowTime.indexOf(' '))){
          // 		msgItem.timeStr = util.tsToDate(new Date().getTime(), 'h:m')
          // 	}else{
          // 		msgItem.timeStr = util.tsToDate(new Date().getTime(), 'M月D日 h:m')
          // 	}

          // }
          this.msgItems.push(msgItem)
          this.setData({
            msgItems: this.msgItems
          })

          this.$nextTick(function () {
            this.chatScrollTop = this.chatScrollTop + 1000 * this.msgItems.length
          })

        }
      };
      http.request(params);
    },

    /**
     * 创建ws
     */
    openWs () {
      var ths = this
      this.imSocketTask = uni.connectSocket({
        url: config.imWsDomain + '/im/websocket/user/' + Base64.encode(uni.getStorageSync('token')) + '/' + this.userInfo.userId,
        complete: () => { }
      });

      this.imSocketTask.onOpen((openRes) => {
        heartCheck.reset().start() // 成功建立连接后，重置心跳检测

        // 发送信息获取聊天记录
        this.getMsgItems()
        this.getOnlineStatus()

      })
      this.imSocketTask.onMessage((res) => {
        //code 1 是新消息 code 2 是聊天记录 code 3 是转接客服
        //code 10~12是错误信息
        let result = JSON.parse(res.data)
        if (result.code !== '00000') {
          result.code = Number(result.code)
        }
        heartCheck.reset().start() // 如果获取到消息，说明连接是正常的，重置心跳检测

        /**
         * 聊天记录
         */
        if (result.code === 2) {
          let msgIds = []
          if (!result.data.pages) {
            // 进行商品链接或订单的判断
            if (ths.$Route.query.prodid && ths.current == 1) {
              ths.getProdInfo(ths.$Route.query.prodid, 1)
            }
            if (ths.$Route.query.orderNumber && ths.current == 1) {
              ths.getProdInfo(ths.$Route.query.orderNumber, 2)
            }
            return
          }
          if (result && result.data.pages) {
            result.data.records = result.data.records.reverse()

            // 进行是否是商品链接的判断
            result.data.records.forEach(item => {

              let a = this.isJSON(item.content)

              if (a && JSON.parse(item.content) instanceof Object) {
                item.prodInfo = JSON.parse(item.content)
              }

              item.timeStr = util.tsToDate(item.timestamp, 'M月D日 h:m')

              if (item.type === 1 && !a) {
                item.content = item.content.indexOf(config.picDomain) === 0 ? item.content : config.picDomain + item.content
              }

              // 往已读列表添加
              if (!item.userUnread) {
                msgIds.push(item.itemId)
                this.totalUserUnread = this.totalUserUnrea - 1
              }

            })

            result.data.records.reduce((prev, cur) => {
              // 将时间更换为某某月某某日 要是是当天即去掉月日
              let now = util.tsToDate(prev.timestamp, 'M月D日 h:m')
              let next = util.tsToDate(cur.timestamp, 'M月D日 h:m')
              if (now.slice(0, now.indexOf(' ')) == next.slice(0, next.indexOf(' '))) {
                cur.timeStr = util.tsToDate(cur.timestamp, 'h:m')
              }

              // 历史记录进行时间段显示判断
              if (result.data.records.length > 2) {
                let timeFlag = this.timeBeApart(prev.timestamp, cur.timestamp)
                if (timeFlag) {
                  delete cur.timeStr
                }
              }
              return cur
            })
            this.totalUserUnread = result.data.totalUserUnread
          }

          // 将消息变更为已读
          let readed = {
            read: 1,
            msgIds,
            toId: this.shopId,
            sendType: this.sendType
          }
          this.imSocketTask.send({
            data: JSON.stringify(readed)
          })

          if (this.current == 1) {

            this.msgItems = result.data.records
            this.setData({
              msgItems: result.data.records,
              pages: result.data.pages
            })

            this.$nextTick(function () {
              setTimeout(() => {
                this.chatScrollTop = this.chatScrollTop + 1200 * result.data.records.length
              }, 1)
            })
          }

          if (this.current != 1) {
            result.data.records = result.data.records.reverse()
            // 数组反转拼接
            result.data.records.forEach(item => {
              this.msgItems.unshift(item)
            })
            this.setData({
              msgItems: this.msgItems
            })

          }

          // 进行商品链接或订单的判断
          if (ths.$Route.query.prodid && ths.current == 1) {
            ths.getProdInfo(ths.$Route.query.prodid, 1)
          }
          if (ths.$Route.query.orderNumber && ths.current == 1) {
            ths.getProdInfo(ths.$Route.query.orderNumber, 2)
          }

          uni.stopPullDownRefresh()
          this.showRefresh = false

        }

        /**
         * 未读信息转成已读
         */
        if (result.code === 5) {

          // if(ths.userSend){
          // 	ths.userRead = false
          // 	ths.userSend = false
          // 	ths.msgItems.push(ths.messageInfo)
          // }

          ths.msgItems.forEach((item) => {
            item.employeeUnread = 1
          })
          ths.setData({
            msgItems: ths.msgItems,
          })
          ths.$nextTick(function () {
            this.chatScrollTop = this.chatScrollTop + 1000 * this.msgItems.length
          })
        }

        if (result.code == 10 || result.code == 11 || result.code == 12) {
          // source: -1  系统提示;    tipsType: 1客服不在线    2用户在别处登陆    3无法获取用户信息
          var tipsItem = {
            source: -1,
            tipsType: result.code == 12 ? 1 : result.code == 11 ? 2 : 3
          }
          this.imSocketTask.close()
          let flag = false
          let delIndex = 0
          this.msgItems.forEach((item, index) => {
            if (item.tipsType == tipsItem.tipsType) {
              flag = true
              delIndex = index
            }
          })
          if (flag) {
            this.msgItems.splice(delIndex, 1)
          }
          this.msgItems.push(tipsItem)
          this.setData({
            msgItems: this.msgItems,
            loginOtherSide: true
          })
          return
        }

        if (!result.data) {
          return
        }

        /**
         * 新的聊天信息
         */
        if (result.code === '00000' || result.code === 4) {
          // 时间转换
          if (this.msgItems.length) {
            // 时间转换
            let prevTime = util.tsToDate(this.msgItems[this.msgItems.length - 1].timestamp, 'M月D日 h:m')
            let nowTime = util.tsToDate(result.data.timestamp, 'M月D日 h:m')
            if (prevTime.slice(0, prevTime.indexOf(' ')) === nowTime.slice(0, nowTime.indexOf(' '))) {
              result.data.timeStr = util.tsToDate(new Date().getTime(), 'h:m')
            } else {
              result.data.timeStr = util.tsToDate(new Date().getTime(), 'M月D日 h:m')
            }
            let timeFlag = this.timeBeApart(this.msgItems[this.msgItems.length - 1].timestamp, new Date().getTime())
            if (timeFlag) {
              delete result.data.timeStr
            }
          }
          let readed = {
            read: 1,
            msgIds: [result.data.itemId],
            toId: this.shopId,
            sendType: this.sendType,
            readNoticeEmployeeId: result.data.employeeId
          }
          this.imSocketTask.send({
            data: JSON.stringify(readed)
          })

          //接受新传过来的消息，加入到聊天栏
          let msgItem = result.data
          if (msgItem.type == 1) {
            msgItem.content = config.picDomain + msgItem.content
          }
          this.msgItems.push(msgItem)
          this.setData({
            isOnline: true,
            msgItems: this.msgItems,
            shopId: msgItem.shopId
          })

          this.$nextTick(function () {
            this.chatScrollTop = this.chatScrollTop + 1000 * this.msgItems.length
          })
        }

        /**
         * 未读信息转成已读
         */
        if (result.code === 16) {
          this.isOnline = result.data.onlineOrOffline
          uni.setNavigationBarTitle({
            title: uni.getStorageSync('appType') != 4 ? this.i18n.mallCustomerService + ` ${this.isOnline ? this.i18n.online : this.i18n.offline}` : this.i18n.mallCustomerService
          })
        }

        this.loginOtherSide = false

      })

      var ths = this
      // 心跳检测, 每隔一段时间检测连接状态，如果处于连接中，就向server端主动发送消息，来重置server端与客户端的最大连接时间，如果已经断开了，发起重连。
      var heartCheck = {
        timeout: 19000, // 19s发一次心跳，比server端设置的连接时间稍微小一点，在接近断开的情况下以通信的方式去重置连接时间。
        serverTimeoutObj: null,
        reset: function () {
          clearTimeout(this.serverTimeoutObj);
          return this;
        },
        start: function () {
          this.serverTimeoutObj = setTimeout(function () {
            if (!ths.imSocketTask) {
              return
            }
            if (ths.imSocketTask.readyState == 1 || ths.imSocketTask._webSocket.readyState == 1) {
              console.log("连接状态，发送消息保持连接");
              ths.imSocketTask.send({ data: JSON.stringify({ sendType: ths.sendType, content: 'HEART_BEAT', msgType: 0, toId: ths.shopId }) });
              heartCheck.reset().start() // 如果获取到消息，说明连接是正常的，重置心跳检测
            } else {
              ths.imSocketTask.close()
              ths.imSocketTask = null
              console.log("断开状态，尝试重连");
              ths.openWs();
            }
          }, this.timeout)
        }
      }

      this.imSocketTask.onclose = (res) => {
        console.log('断线,开始重连')
        this.openWs()
      }

    },
    /**
     * ws关闭
     */
    closeWs () {
      this.imSocketTask.close()
      this.imSocketTask = null
    },
    /**
     * 发送信息
     */
    sendText (type) {

      // type 1 = 发送消息  type 2 = 发送商品链接

      // source 0 是平台  1 是商家  2 是顾客

      if (type === 1) {
        if (this.textMsg === '' || this.textMsg.match(/^\s+$/)) {
          return
        }
      }
      let messageInfo = {
        toId: this.shopId,
        content: type == 1 ? this.textMsg : JSON.stringify(this.prodInfo),
        msgType: 0,
        sendType: this.sendType // 0发给平台   1发给商家
      };
      this.addMessage(messageInfo);
      this.textMsg = ''

    },
    /**
     * @param {Object} messageInfo
     * 将新发送的消息添加至页面
     */
    addMessage (messageInfo) {
      this.userRead = true
      this.userSend = true
      this.imSocketTask.send({
        data: JSON.stringify(messageInfo)
      })

      if (messageInfo.msgType === 1) {
        messageInfo.content = config.picDomain + messageInfo.content
      }

      // 发送商品链接需要由JSON格式转换为对象
      let a = this.isJSON(messageInfo.content)

      if (a && JSON.parse(messageInfo.content) instanceof Object) {
        messageInfo.prodInfo = JSON.parse(messageInfo.content)
      }

      let userInfo = this.userInfo
      let msgItem = {
        userName: userInfo.nickName,
        userHeadUrl: userInfo.pic,
        employeeUnread: 0,
        type: messageInfo.msgType,
        source: 2,
        timestamp: new Date().getTime(),
        content: messageInfo.content,
        prodInfo: messageInfo.prodInfo
      }

      if (!this.msgItems.length) {

        msgItem.timeStr = util.tsToDate(new Date().getTime(), 'M月D日 h:m')

      } else {

        let prevTime = util.tsToDate(this.msgItems[this.msgItems.length - 1].timestamp, 'M月D日 h:m')

        let nowTime = util.tsToDate(new Date().getTime(), 'M月D日 h:m')
        if (prevTime.slice(0, prevTime.indexOf(' ')) == nowTime.slice(0, nowTime.indexOf(' '))) {
          msgItem.timeStr = util.tsToDate(new Date().getTime(), 'h:m')
        } else {
          msgItem.timeStr = util.tsToDate(new Date().getTime(), 'M月D日 h:m')
        }

        let timeFlag = this.timeBeApart(this.msgItems[this.msgItems.length - 1].timestamp, new Date().getTime())
        if (timeFlag) {
          delete msgItem.timeStr
        }

      }

      this.messageInfo = msgItem // 发送的信息存储起来，用于已读未读
      msgItem.timestamp = new Date().getTime()

      this.msgItems.push(msgItem)
      this.setData({
        msgItems: this.msgItems,
      })

      this.$nextTick(function () {
        this.chatScrollTop = this.chatScrollTop + 1000 * this.msgItems.length
      })

    },

    /**
     * 进行相隔时间判断
     *
     * true 删除显示时间
     * false 保留显示时间
     */
    timeBeApart (uppTime, preTime) {
      if (!uppTime) {
        return false
      }
      var dateDiff = preTime - uppTime// 时间差的毫秒数
      var dayDiff = Math.floor(dateDiff / (24 * 3600 * 1000))// 计算出相差天数
      var leave1 = dateDiff % (24 * 3600 * 1000)    // 计算天数后剩余的毫秒数
      var hours = Math.floor(leave1 / (3600 * 1000))// 计算出小时数
      // 计算相差分钟数
      var leave2 = leave1 % (3600 * 1000)    // 计算小时数后剩余的毫秒数
      var minutes = Math.floor(leave2 / (60 * 1000))// 计算相差分钟数

      // console.log('相差' + dayDiff + '天')
      // console.log('相差' + hours + '小时')
      // console.log('相差' + minutes + '分钟')

      if (dayDiff >= 1 || hours >= 1 || minutes > 4) {
        return false
      } else {
        return true
      }
    },

    /**
     * 更多功能(点击+弹出)
     */
    showMore () {
      if (this.hideMore) {
        this.hideMore = false;
        this.openDrawer();
      } else {
        this.hideDrawer();
      }
    },
    /**
     * 打开抽屉
     */
    openDrawer () {
      this.hideMore = false;
      this.$nextTick(() => {
        this.screenHeight = this.oldScreenHeight - 90
        this.chatScrollTop += 1
      })
    },
    /**
     * 隐藏抽屉
     */
    hideDrawer (wxNeedSub, noSliding) {
      // #ifdef H5
      this.$nextTick(() => {
        this.screenHeight = this.oldScreenHeight
      })
      // #endif

      // #ifdef MP-WEIXIN || APP-PLUS
      this.$nextTick(() => {
        if (wxNeedSub) {
          this.screenHeight = this.oldScreenHeight - 90
        } else {
          this.screenHeight = this.oldScreenHeight
        }
      })
      // #endif
      this.hideMore = true;

      //  防止滑动时页面触底
      if (!noSliding) {
        this.$nextTick(() => {
          this.chatScrollTop += 1
        })
      }
    },

    /**
     * 获取焦点，如果不是选表情ing,则关闭抽屉
     */
    textareaFocus () {

      // #ifdef H5
      this.fixedFlag = true
      this.popupLayerClass = '';
      // #endif

      this.hideDrawer(!this.hideMore)
    },

    // 失去焦点软键盘变回原样
    listeningfocus () {
      this.fixedFlag = null
      this.hideDrawer(false)
    },

    hideKeyboard () {
      uni.hideKeyboard()
      this.hideDrawer(false, true)
    },
    /**
     * 选择图片发送
     */
    chooseImage () {
      this.getImage('album');
    },
    /**
     * 拍照发送
     */
    camera () {
      this.getImage('camera');
    },

    // 触摸开始
    hideKeyboard (e) {
      uni.hideKeyboard()
      this.hideDrawer(false, true)
      this.curSpacing = 1
      this.startY = e.changedTouches[0].pageY
      this.freshStatus = 'more'
    },
    // 触摸结束
    touchEnd () {
      if (this.freshStatus == 'end') {
        // 延迟 500 毫秒，显示 “刷新中”，防止请求速度过快不显示
        this.current += 1;
        if (this.loginOtherSide) {
          uni.stopPullDownRefresh()
          uni.showToast({
            title: this.i18n.chat.loginOtherSide,
            icon: 'none',
          })
          this.showRefresh = false
        }
        else if (this.current <= this.pages) {
          this.freshStatus == 'fresh'
          this.getMsgItems()
        } else {
          uni.stopPullDownRefresh()
          uni.showToast({
            title: this.i18n.allLoaded,
            icon: 'none',
          })
          this.showRefresh = false
        }
      } else {
        this.showRefresh = false
      }
    },
    // 滚轮移动
    bindscroll (e) {
      this.$nextTick(() => {
        this.scollTopTag = e.detail.scrollTop
      })
    },
    // 触摸移动
    touchMove (e) {
      if (this.scollTopTag !== 0) {
        const query = uni.createSelectorQuery()
        query.select('#input-text').scrollOffset()
        query.exec(res => {
          this.scollTopTag = res[0].scrollTop
        })
      }
      if (this.scollTopTag > 0) { return }
      e.preventDefault();
      let endY = e.changedTouches[0].pageY;
      let startY = this.startY;
      let dis = endY - startY;
      // 判断是否下拉
      if (dis <= 0) {
        return;
      }
      let offsetTop = e.currentTarget.offsetTop;
      if (dis > 20) {
        this.showRefresh = true
        // this.freshStatus = 'end'
        if (dis > 50) {
          this.freshStatus = 'end'
        } else {
          this.freshStatus = 'more'
        }
      } else {
        this.showRefresh = false
      }
    },
    /**
     * @param {Object} path
     * 上传图片
     */
    uploadImg (path) {
      var params = {
        url: "/p/file/uploadImFile",
        filePath: path,
        name: 'file',
        callBack: (res) => {
          let messageInfo = {
            toId: this.shopId,
            content: res.filePath,
            sendType: this.sendType,
            msgType: 1
          };
          this.addMessage(messageInfo);
        }
      };
      http.upload(params);
    },
    /**
     * @param {Object} type
     * 选照片 or 拍照
     */
    getImage (type) {
      this.hideDrawer();

      // const agree = localAgree('fileAgree', '提示', '发送图片或拍照需要授权存储功能,是否授权', () => {
      //   this.getImage(type)
      // }, () => { })
      // if (!agree) {
      //   return
      // }
      uni.chooseImage({
        sourceType: [type],
        sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图，默认二者都有
        success: res => {
          if (util.lessThan2M(res.tempFiles)) {
            for (let i = 0; i < res.tempFilePaths.length; i++) {
              uni.getImageInfo({
                src: res.tempFilePaths[i],
                success: image => {
                  this.uploadImg(res.tempFilePaths[i]);
                }
              });
            }
          }
        }
      });
    },
    /**
     * @param {Object} msg
     * 预览图片
     */
    showPic (msg) {
      var list = [];
      list.push(msg);
      uni.previewImage({
        indicator: 'none',
        current: 0,
        urls: list
      });
    },
    /**
     * 用于阻止滚动的空方法
     */
    discard () { },

    /**
     * 链接点击去往商品详情
     */
    toProdDetail (prodInfo) {
      if (prodInfo.orderFlag) {
        uni.navigateTo({
          url: '/pages/order-detail/order-detail?orderNum=' + prodInfo.orderNumber
        })
      } else {
        uni.navigateTo({
          url: '/pages/prod/prod?prodid=' + prodInfo.prodId
        })
      }
    },
    noServiceDialog () {
      uni.showModal({
        title: '提示',
        content: '如果客服离线,请联系客服手机号: \n\n' + 17690917700,
        showCancel: true,
        confirmText: '关闭',
        cancelText: '复制手机号',
        success: function (res) {
          if (res.confirm) {
            // console.log('用户点击确定');
            // 关闭
          } else if (res.cancel) {
            let phone = '17690917700'
            uni.setClipboardData({
              data: phone, // 设置要复制的文本内容
              success (res) {
                console.log("成功复制到剪贴板");
              },
              fail (err) {
                console.error("复制失败", err);
              }
            })
          }
        }
      });
    },
  }
};
</script>

<style>
page {
  background-color: #f5f6fa;
  /* max-height: 100%; */
  overflow: hidden;
  padding-bottom: constant(safe-area-inset-bottom);
  padding-bottom: env(safe-area-inset-bottom);
}

.chat-container {
  display: flex;
  position: static;
  height: 100%;
  width: 100%;
  flex-wrap: wrap;
}

.chatad {
  position: fixed;
}

@font-face {
  font-family: "HMfont-home";
  src: url("data:application/x-font-woff2;charset=utf-8;base64,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")
    format("woff2");
}
.icon {
  font-family: "HMfont-home" !important;
  font-size: 56upx;
  font-style: normal;
  color: #333;
}

.icon.biaoqing:before {
  content: "";
}

.icon.jianpan:before {
  content: "";
}

.icon.yuyin:before {
  content: "";
}

.icon.tupian:before {
  content: "";
}

.icon.chehui:before {
  content: "";
}

.icon.luyin:before {
  content: "";
}

.icon.luyin2:before {
  content: "";
}

.icon.hongbao:before {
  content: "";
}

.icon.tupian2:before {
  content: "";
}

.icon.paizhao:before {
  content: "";
}

.icon.close:before {
  content: "";
}

.icon.to:before {
  content: "";
}
.hidden {
  display: none !important;
}

.popup-layer {
  /* transition: all 0.15s linear; */
  width: 96%;
  /* height: 180rpx; */
  padding: 0 2%;
  padding-bottom: 0;
  /* position: fixed;
		z-index: 20;
		bottom: 0;
		top: 100%; */
}

.popup-layer.showLayer {
  transform: translate3d(0, -180rpx, 0);
}

.popup-layer .more-layer {
  width: 100%;
  height: 180rpx;
  padding-bottom: constant(safe-area-inset-bottom);
  padding-bottom: env(safe-area-inset-bottom);
}

.popup-layer .more-layer .list {
  width: 100%;
  display: flex;
  flex-wrap: wrap;
}

.popup-layer .more-layer .list .box {
  width: 18vw;
  height: 18vw;
  border-radius: 20upx;
  background-color: #fff;
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 2vw 3vw 2vw 3vw;
}

.popup-layer .more-layer .list .box .icon {
  font-size: 70upx;
}

.input-box {
  width: 98%;
  /* height: 88rpx; */
  padding: 0 2%;
  background-color: #fff;
  display: flex;
  /* position: fixed; */
  z-index: 20;
  /* bottom: calc(env(safe-area-inset-bottom)/2); */
  /* transition: all 0.15s linear; */
  border-bottom: solid 1upx #ddd;
}
.input-box.showLayer {
  transform: translate3d(0, -180rpx, 0);
}

.input-box .more {
  flex-shrink: 0;
  width: 90upx;
  height: 90rpx;
  display: flex;
  justify-content: center;
  align-items: center;
}

.input-box .send {
  margin-left: 20rpx;
  margin-right: 20rpx;
  padding-bottom: 10rpx;
  flex-shrink: 0;
  width: 100upx;
  height: 86rpx;
  display: flex;
  align-items: center;
}

.input-box .send .btn {
  width: 101rpx;
  height: 58rpx;
  background: #ff6d13;
  opacity: 1;
  border-radius: 16px;
  font-size: 13px;
  font-family: PingFang SC;
  font-weight: 400;
  line-height: 58rpx;
  color: #ffffff;
  opacity: 1;
  text-align: center;
}

.input-box .textbox {
  width: 100%;
  min-height: 58rpx;
  margin-top: 15upx;
}

.input-box .textbox .text-mode {
  width: 100%;
  min-height: 56rpx;
  display: flex;
  background-color: #fff;
  border-radius: 40upx;
}

.input-box .textbox .text-mode .box {
  width: 100%;
  padding-left: 30upx;
  padding-right: 30upx;
  min-height: 58rpx;
  display: flex;
  align-items: center;
  background: #ffffff;
  border: 1px solid #dddddd;
  opacity: 1;
  border-radius: 16px;
}
.input-box .textbox .text-mode .box textarea {
  width: 100%;
}

.input-box .textbox .text-mode .em {
  flex-shrink: 0;
  width: 80upx;
  padding-left: 10upx;
  height: 70upx;
  display: flex;
  justify-content: center;
  align-items: center;
}

.record {
  width: 40vw;
  height: 40vw;
  position: fixed;
  top: 55%;
  left: 30%;
  background-color: rgba(0, 0, 0, 0.6);
  border-radius: 20upx;
}

.record .ing {
  width: 100%;
  height: 30vw;
  display: flex;
  justify-content: center;
  align-items: center;
}

@keyframes volatility {
  0% {
    background-position: 0% 130%;
  }

  20% {
    background-position: 0% 150%;
  }

  30% {
    background-position: 0% 155%;
  }

  40% {
    background-position: 0% 150%;
  }

  50% {
    background-position: 0% 145%;
  }

  70% {
    background-position: 0% 150%;
  }

  80% {
    background-position: 0% 155%;
  }

  90% {
    background-position: 0% 140%;
  }

  100% {
    background-position: 0% 135%;
  }
}

.record .ing .icon {
  background-image: linear-gradient(to bottom, #f09b37, #fff 50%);
  background-size: 100% 200%;
  animation: volatility 1.5s ease-in-out -1.5s infinite alternate;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  font-size: 150upx;
  color: #f09b37;
}

.record .cancel {
  width: 100%;
  height: 30vw;
  display: flex;
  justify-content: center;
  align-items: center;
}

.record .cancel .icon {
  color: #fff;
  font-size: 150upx;
}

.record .tis {
  width: 100%;
  height: 10vw;
  display: flex;
  justify-content: center;
  font-size: 28upx;
  color: #fff;
}

.record .tis.change {
  color: #f09b37;
}

.content {
  width: 100%;
  padding-top: 100rpx;
  /* margin-bottom: 100rpx; */
  box-sizing: border-box;
}

/* #ifdef MP-WEIXIN || APP-PLUS */
.content {
  padding-top: 0;
}

/* #endif */
.content .msg-list {
  width: 100%;
}

.content .msg-list .loading {
  display: flex;
  justify-content: center;
}

@keyframes stretchdelay {
  0%,
  40%,
  100% {
    transform: scaleY(0.6);
  }

  20% {
    transform: scaleY(1);
  }
}

.content .msg-list .loading .spinner {
  margin: 20upx 0;
  width: 60upx;
  height: 100upx;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.content .msg-list .loading .spinner view {
  background-color: #f95251;
  height: 50upx;
  width: 6upx;
  border-radius: 6upx;
  animation: stretchdelay 1.2s infinite ease-in-out;
}

.content .msg-list .loading .spinner .rect2 {
  animation-delay: -1.1s;
}

.content .msg-list .loading .spinner .rect3 {
  animation-delay: -1s;
}

.content .msg-list .loading .spinner .rect4 {
  animation-delay: -0.9s;
}

.content .msg-list .loading .spinner .rect5 {
  animation-delay: -0.8s;
}

.content .msg-list .row {
  padding: 30rpx;
}

.content .msg-list .row .system {
  display: flex;
  justify-content: center;
}

.content .msg-list .row .system view {
  padding: 0 30upx;
  height: 50upx;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #c9c9c9;
  color: #fff;
  font-size: 24upx;
  border-radius: 40upx;
}

.content .msg-list .row .system .red-envelope image {
  margin-right: 5upx;
  width: 30upx;
  height: 30upx;
}

.content .msg-list .row:first-child {
  margin-top: 20upx;
}

.content .msg-list .row .my .left,
.content .msg-list .row .other .right {
  width: 100%;
  display: flex;
  align-items: center;
}

.content .msg-list .row .my .left .bubble,
.content .msg-list .row .other .right .bubble {
  max-width: 70%;
  min-height: 50upx;
  border-radius: 10upx;
  padding: 15upx 20upx;
  display: flex;
  align-items: center;
  font-size: 32upx;
  word-break: break-word;
}

.content .msg-list .row .my .left .bubble .longimage,
.content .msg-list .row .other .right .bubble .longimage {
  width: 300rpx;
  height: auto;
}

.content .msg-list .row .my .left .bubble .squareimage,
.content .msg-list .row .other .right .bubble .squareimage {
  width: 300rpx;
  height: 300rpx;
}

.content .msg-list .row .my .left .bubble.red-envelope,
.content .msg-list .row .other .right .bubble.red-envelope {
  background-color: transparent;
  padding: 0;
  overflow: hidden;
  position: relative;
  justify-content: center;
  align-items: flex-start;
}

.content .msg-list .row .my .left .bubble.red-envelope image,
.content .msg-list .row .other .right .bubble.red-envelope image {
  width: 250upx;
  height: 313upx;
}

.content .msg-list .row .my .left .bubble.red-envelope .tis,
.content .msg-list .row .other .right .bubble.red-envelope .tis {
  position: absolute;
  top: 6%;
  font-size: 26upx;
  color: #9c1712;
}

.content .msg-list .row .my .left .bubble.red-envelope .blessing,
.content .msg-list .row .other .right .bubble.red-envelope .blessing {
  position: absolute;
  bottom: 14%;
  color: #e9b874;
  width: 80%;
  text-align: center;
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}

.content .msg-list .row .my .right,
.content .msg-list .row .other .left {
  flex-shrink: 0;
  width: 80upx;
  height: 80upx;
}

.content .msg-list .row .my .right image,
.content .msg-list .row .other .left image {
  width: 80upx;
  height: 80upx;
  border-radius: 10upx;
}

.content .msg-list .row .my {
  width: 100%;
  display: flex;
  justify-content: flex-end;
}

.content .msg-list .row .my .left {
  min-height: 80upx;
  justify-content: flex-end;
  flex-wrap: wrap;
}

.content .msg-list .row .my .left .bubble {
  background-color: #f95251;
  color: #fff;
  opacity: 1;
  border-radius: 8px 0px 8px 8px;
}

.content .msg-list .row .other .right .bubble {
  opacity: 1;
  border-radius: 0px 8px 8px 8px;
}

.content .msg-list .row .my .left .no-bg {
  background-color: none;
}

@keyframes my-play {
  0% {
    transform: translateX(80%);
  }

  100% {
    transform: translateX(0%);
  }
}

.content .msg-list .row .my .left .bubble.play .icon:after {
  border-left: solid 10upx rgba(240, 108, 122, 0.5);
  animation: my-play 1s linear infinite;
}

.phone-icon {
  width: 60rpx;
  height: 60rpx;
}

.content .msg-list .row .my .right {
  margin-left: 15upx;
}

.content .msg-list .row .other {
  width: 100%;
  display: flex;
}

.content .msg-list .row .other .left {
  margin-right: 15upx;
}

.content .msg-list .row .other .right {
  flex-wrap: wrap;
}

.content .msg-list .row .other .right .username,
.content .msg-list .row .my .left .username {
  width: 100%;
  height: 45upx;
  font-size: 24upx;
  color: #999;
  display: flex;
  align-items: center;
}

.content .msg-list .row .my .left .username {
  justify-content: flex-end;
}

.content .msg-list .row .my .left .username .name {
  width: auto;
  max-width: 250rpx;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.content .msg-list .row .my .left .username .time {
  text-align: center;
  margin-left: 40rpx;
}

.content .msg-list .row .other .right .username .name {
  margin-right: 50rpx;
  max-width: 250rpx;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.content .msg-list .row .other .right .bubble {
  background-color: #fff;
  color: #333;
}

@keyframes other-play {
  0% {
    transform: translateX(-80%);
  }

  100% {
    transform: translateX(0%);
  }
}

.content .msg-list .row .other .right .bubble.play .icon:after {
  border-right: solid 10upx rgba(255, 255, 255, 0.8);
  animation: other-play 1s linear infinite;
}

.windows .mask {
  position: fixed;
  top: 100%;
  width: 100%;
  height: 100%;
  z-index: 1000;
  background-color: rgba(0, 0, 0, 0.6);
  opacity: 0;
  transition: opacity 0.2s ease-out;
}

.windows .layer {
  position: fixed;
  width: 80%;
  height: 70%;
  left: 10%;
  z-index: 1001;
  border-radius: 20upx;
  overflow: hidden;
  top: 100%;
  transform: scale3d(0.5, 0.5, 1);
  transition: all 0.2s ease-out;
}

.windows.show {
  display: block;
}

.windows.show .mask {
  top: 0;
  opacity: 1;
}

.windows.show .layer {
  transform: translate3d(0, -85vh, 0) scale3d(1, 1, 1);
}

.windows.hide {
  display: block;
}

.windows.hide .mask {
  top: 0;
  opacity: 0;
}

.open-redenvelope {
  width: 100%;
  height: 70vh;
  background-color: #cf3c35;
  position: relative;
}

.open-redenvelope .top {
  width: 100%;
  background-color: #fe5454;
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  border-radius: 0 0 100% 100%;
  box-shadow: inset 0 -20upx 0 #9c1712;
  margin-bottom: 65upx;
}

.open-redenvelope .top .close-btn {
  width: 100%;
  height: 80upx;
  display: flex;
  justify-content: flex-end;
  margin-bottom: 30upx;
}

.open-redenvelope .top .close-btn .icon {
  color: #9c1712;
  margin-top: 10upx;
  margin-right: 10upx;
}

.open-redenvelope .top image {
  width: 130upx;
  height: 130upx;
  border: solid 12upx #cf3c35;
  border-radius: 100%;
  margin-bottom: -65upx;
}

.open-redenvelope .from,
.open-redenvelope .blessing,
.open-redenvelope .money,
.open-redenvelope .showDetails {
  width: 90%;
  padding: 5upx 5%;
  display: flex;
  justify-content: center;
  font-size: 32upx;
  color: #fff;
}

.open-redenvelope .money {
  font-size: 100upx;
  color: #f8d757;
  display: flex;
  padding-top: 20upx;
}

.open-redenvelope .showDetails {
  position: absolute;
  bottom: 20upx;
  align-items: center;
  font-size: 28upx;
  color: #f8d757;
}

.open-redenvelope .showDetails .icon {
  font-size: 26upx;
  color: #f8d757;
}

/* 店铺信息 */
.shop-info {
  width: 100%;
  height: 100rpx;
  position: fixed;
  top: 0;
  background-color: #ffffff;
  line-height: 100rpx;
  text-align: center;
  z-index: 999;
  display: flex;
  align-items: center;
  font-size: 32rpx;
  box-shadow: 2rpx 4rpx 8rpx 0rpx #ddd;
}

.flex-wrap {
  flex: auto;
}

/* 返回图标 */
.back-icon {
  position: absolute;
  left: 0;
  top: 36rpx;
  width: 50rpx;
  height: 30rpx;
  transform: rotate(90deg);
}

.shop-tit {
  text-align: center;
  max-width: 80%;
  margin: 0 auto;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.shop-tit .shop-status {
  font-size: 28rpx;
  margin-left: 10rpx;
}

.shop-tit .in {
  color: #6190e8;
}

.shop-tit .out {
  color: #999;
}

/* 系统提示 */
.sys-tips {
  display: flex;
  justify-content: center;
}

.tips-content {
  color: #999999;
  font-size: 28rpx;
}

/* +图标 */
.add {
  width: 66rpx;
  height: 66rpx;
}

/* 中间时间样式 */
.topTime {
  text-align: center;
  margin-bottom: 15px;
  height: 28rpx;
  font-size: 10px;
  font-family: PingFang SC;
  font-weight: 400;
  line-height: 28rpx;
  color: #aaaaaa;
  opacity: 1;
}

/* 发送链接样式 */
.link-box {
  padding: 16rpx 16rpx 0 16rpx;
  margin: 0 32rpx 0rpx 32rpx;
  /* height: 210rpx; */
  background: #ffffff;
  border: 1px solid #e5e7eb;
  opacity: 1;
}
.link-prod {
  display: flex;
  padding-bottom: 18rpx;
  border-bottom: 1px solid #eeeeee;
}
.link-prod img {
  width: 100rpx;
  height: 100rpx;
}
.link-prod .link-detail {
  display: flex;
  width: 100%;
  flex-direction: column;
  justify-content: space-between;
  margin-top: 2rpx;
  margin: 0 15rpx;
}
.link-detail .prod-name {
  font-size: 10px;
  font-family: PingFang SC;
  padding: 0 10rpx;
  font-weight: 400;
  color: #333333;
  opacity: 1;
  word-break: break-word;
}
.link-prod .prod-price {
  display: flex;
  justify-content: space-between;
  font-size: 10px;
  font-family: PingFang SC;
  padding: 10rpx 0;
  font-weight: 400;
  color: #999999;
  opacity: 1;
}
.link-send {
  font-size: 12px;
  font-family: PingFang SC;
  font-weight: 400;
  line-height: 40rpx;
  padding-top: 20rpx;
  text-align: center;
  color: #ff6d13;
}
.link-send-right {
  width: 10rpx;
  height: 17rpx;
  margin-left: 14rpx;
  display: inline-block;
  background: url("https://mall-1312577323.cos.ap-chengdu.myqcloud.com/mall/images/icon/link-send.png");
}

/* 商品链接样式 */
.prod-link,
.link-box {
  width: 85%;
  background: #ffffff;
  border: 1px solid #e5e7eb;
  /* -webkit-box-sizing: border-box;
		box-sizing: border-box; */
  margin-top: 6px;
  padding: 25rpx 0 25rpx 12px;
}
.prod-number {
  margin-top: -14rpx;
  margin-bottom: 20rpx;
  font-size: 20rpx;
}
.prod-no {
  padding: none;
  border-bottom: none;
}
.unread {
  font-size: 24rpx;
  color: #aaaaaa;
  margin-right: 18rpx;
}

.un-read-tips {
  background-color: #fff;
  padding: 7rpx;
  padding: 20rpx 25rpx 20rpx 30rpx;
  font-size: 12px;
  border-radius: 40rpx 0 0 40rpx;
  position: fixed;
  color: #ff6d13;
  top: 120rpx;
  right: 0;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  align-items: center;
  -webkit-box-shadow: 1px 1px 2rpx 0 #aaa;
  box-shadow: 1px 1px 2rpx 0 #aaa;
}
.un-read-tips image {
  width: 24rpx;
  height: 24rpx;
}
.un-read-icon {
  margin-right: 8rpx;
  margin-bottom: 1px;
}

.lzy-loading {
  margin-right: 20rpx;
  float: left;
  width: 40rpx;
  height: 40rpx;
  border-radius: 50%;
  border: 1px solid #f0f0f0;
  border-left: 1px solid #6190e8;
  animation: load 1s linear infinite;
  -webkit-animation: load 1s linear infinite;
}
@-webkit-keyframes load {
  from {
    -webkit-transform: rotate(0deg);
  }
  to {
    -webkit-transform: rotate(360deg);
  }
}
@keyframes load {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
</style>
